<template>
  <div>
    <canvas id="gameCanvas" width="1000" height="750"></canvas>
    <div class="scoreboard">
      <p>分数: {{ score }}</p>
      <p>剩余机会: {{ chances }}</p>
    </div>
  </div>
</template>

<script>
export default {
  name: 'GameComponent',
  data() {
    return {
      score: 0,
      chances: 5,
      trashItems: [
        { type: 'recyclable', width: 25, height: 25, color: 'blue' },
        { type: 'organic', width: 25, height: 25, color: 'green' },
        { type: 'toxic', width: 25, height: 25, color: 'red' }
      ],
      bins: [
        { type: 'recyclable', x: 400, y: 420, width: 100, height: 100, color: 'blue' },
        { type: 'organic', x: 600, y: 320, width: 100, height: 100, color: 'green' },
        { type: 'toxic', x: 800, y: 220, width: 100, height: 100, color: 'red' }
      ],
      platforms: [
        { x: 375, y: 530, width: 150, height: 20, color: 'gray' },
        { x: 575, y: 430, width: 150, height: 20, color: 'gray' },
        { x: 775, y: 330, width: 150, height: 20, color: 'gray' }
      ],
      selectedTrash: null,
      isDragging: false,
      startX: 150,
      startY: 450,
      currentX: 0,
      currentY: 0,
      gravity: 0.5,
      friction: 0.5,
      groundFriction: 0.5,
      catapult: { x: 150, y: 450, width: 20, height: 100 },
      touchGroundTime: null
    };
  },
  mounted() {
    const canvas = this.$el.querySelector('#gameCanvas');
    const ctx = canvas.getContext('2d');

    const draw = () => {
      ctx.clearRect(0, 0, canvas.width, canvas.height);

      // Draw platforms
      this.platforms.forEach(platform => {
        ctx.fillStyle = platform.color;
        ctx.fillRect(platform.x, platform.y, platform.width, platform.height);
      });

      // Draw bins
      this.bins.forEach(bin => {
        ctx.fillStyle = bin.color;
        ctx.fillRect(bin.x, bin.y, bin.width, bin.height);
      });

      // Draw trash items
      if (this.selectedTrash) {
        ctx.fillStyle = this.selectedTrash.color;
        ctx.fillRect(this.selectedTrash.x, this.selectedTrash.y, this.selectedTrash.width, this.selectedTrash.height);
      }

      // Draw slingshot
      ctx.beginPath();
      ctx.moveTo(this.catapult.x, this.catapult.y);
      if (this.isDragging) {
        ctx.lineTo(this.currentX, this.currentY);
      } else if (this.selectedTrash) {
        ctx.lineTo(this.selectedTrash.x + this.selectedTrash.width / 2, this.selectedTrash.y + this.selectedTrash.height / 2);
      }
      ctx.stroke();

      // Draw catapult
      ctx.fillStyle = 'brown';
      ctx.fillRect(this.catapult.x - this.catapult.width / 2, this.catapult.y - this.catapult.height, this.catapult.width, this.catapult.height);
    };

    const resetGame = () => {
      this.score = 0;
      this.chances = 5;
      this.loadNextTrash();
      draw();
    };

    const checkCollision = (trash) => {
      this.bins.forEach(bin => {
        if (trash.x > bin.x && trash.x < bin.x + bin.width &&
            trash.y > bin.y && trash.y < bin.y + bin.height) {
          if (trash.type === bin.type && !trash.scored) {
            this.score += 10;
            trash.scored = true; // 标记垃圾已经得分
          }
        }
      });
    };

    this.loadNextTrash = () => {
      if (this.trashItems.length > 0) {
        const nextTrash = this.trashItems.shift();
        nextTrash.x = this.catapult.x - nextTrash.width / 2;
        nextTrash.y = this.catapult.y - nextTrash.height / 2;
        nextTrash.velocityX = 0;
        nextTrash.velocityY = 0;
        nextTrash.scored = false; // 初始化得分标记
        this.selectedTrash = nextTrash;
        this.touchGroundTime = null;
      } else {
        this.selectedTrash = null;
      }
    };

    const updatePhysics = () => {
      if (this.selectedTrash) {
        this.selectedTrash.velocityY += this.gravity;
        this.selectedTrash.x += this.selectedTrash.velocityX;
        this.selectedTrash.y += this.selectedTrash.velocityY;

        // Check for collisions with canvas boundaries
        if (this.selectedTrash.x <= 0 || this.selectedTrash.x + this.selectedTrash.width >= canvas.width) {
          this.selectedTrash.velocityX *= -this.friction;
        }
        if (this.selectedTrash.y + this.selectedTrash.height >= canvas.height) {
          this.selectedTrash.velocityY *= -this.friction;
          this.selectedTrash.y = canvas.height - this.selectedTrash.height; // Ensure it stays on the ground
          this.selectedTrash.velocityX *= this.groundFriction; // Apply ground friction
          if (Math.abs(this.selectedTrash.velocityX) < 0.1) {
            this.selectedTrash.velocityX = 0; // Stop the trash if it's moving very slowly
          }

          // Start the timer when the trash touches the ground
          if (!this.touchGroundTime) {
            this.touchGroundTime = Date.now();
          } else if (Date.now() - this.touchGroundTime > 3000) {
            // If the trash has been on the ground for more than 3 seconds, remove it
            this.selectedTrash = null;
            this.loadNextTrash();
          }
        } else {
          this.touchGroundTime = null; // Reset the timer if the trash is not on the ground
        }

        // Ensure the trash stays within the canvas boundaries
        this.selectedTrash.x = Math.max(0, Math.min(this.selectedTrash.x, canvas.width - this.selectedTrash.width));
        this.selectedTrash.y = Math.max(0, Math.min(this.selectedTrash.y, canvas.height - this.selectedTrash.height));

        // Check for collisions with platforms
        this.platforms.forEach(platform => {
          if (this.selectedTrash.x < platform.x + platform.width &&
              this.selectedTrash.x + this.selectedTrash.width > platform.x &&
              this.selectedTrash.y < platform.y + platform.height &&
              this.selectedTrash.y + this.selectedTrash.height > platform.y) {
            this.selectedTrash.velocityY *= -this.friction;
            this.selectedTrash.y = platform.y - this.selectedTrash.height;
            this.selectedTrash.velocityX *= this.groundFriction;
            if (Math.abs(this.selectedTrash.velocityX) < 0.1) {
              this.selectedTrash.velocityX = 0;
            }
            if (!this.touchGroundTime) {
              this.touchGroundTime = Date.now();
            } else if (Date.now() - this.touchGroundTime > 3000) {
              this.selectedTrash = null;
              this.loadNextTrash();
            }
          }
        });

        checkCollision(this.selectedTrash);
      }
    };

    const animate = () => {
      updatePhysics();
      draw();
      if (this.selectedTrash || this.trashItems.length > 0) {
        requestAnimationFrame(animate);
      } else {
        this.chances--;
        if (this.chances === 0) {
          if (this.score >= 30) {
            alert('游戏成功!');
          } else {
            alert('游戏失败!');
          }
          resetGame();
        } else {
          this.loadNextTrash();
        }
      }
    };

    canvas.addEventListener('mousedown', (e) => {
      if (this.selectedTrash) {
        this.isDragging = true;
        this.currentX = e.offsetX;
        this.currentY = e.offsetY;
      }
    });

    canvas.addEventListener('mousemove', (e) => {
      if (this.isDragging) {
        this.currentX = e.offsetX;
        this.currentY = e.offsetY;
        draw();
      }
    });

    canvas.addEventListener('mouseup', (e) => {
      if (this.isDragging && this.selectedTrash) {
        const angle = Math.atan2(this.catapult.y - e.offsetY, this.catapult.x - e.offsetX);
        const distance = Math.hypot(this.catapult.x - e.offsetX, this.catapult.y - e.offsetY);
        this.selectedTrash.velocityX = Math.cos(angle) * distance * 0.1;
        this.selectedTrash.velocityY = Math.sin(angle) * distance * 0.1;
        this.isDragging = false;
        animate();
      }
    });

    this.loadNextTrash();
    draw();
  }
}
</script>

<style scoped>
canvas {
  border: 1px solid black;
}

.scoreboard {
  position: absolute;
  top: 10px;
  right: 10px;
  background: white;
  padding: 10px;
  border: 1px solid black;
}
</style>